package com.sias.resolver;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.MethodParameter;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockPart;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.HandlerMapping;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author 吴文杰
 * @version 1.0
 * @since 2023/6/8 12:26
 */
public class SomeResolver {
  public static void main(String[] args) throws NoSuchMethodException {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
    HttpServletRequest multiRequest = mockRequest();

    // 1.控制器方法被封装为HandlerMethod
    HandlerMethod handlerMethod = new HandlerMethod(new Controller(),
            Controller.class.getMethod("test", String.class, String.class, int.class, String.class,
                    MultipartFile.class, int.class, String.class, String.class, String.class,
                    HttpServletRequest.class, User.class, User.class, User.class));
    // 准备对象绑定与类型转换

    // 准备 MethodAndViewContainer 用来存储中间model结果
    for (MethodParameter parameter : handlerMethod.getMethodParameters()) {

      String annotations = Arrays.stream(parameter.getParameterAnnotations()).map(a -> a.annotationType().getSimpleName()).collect(Collectors.toList()).toString();
      System.out.println(annotations);

      String str = annotations.length() > 0 ? "@" + annotations : "";

      parameter.initParameterNameDiscovery(new DefaultParameterNameDiscoverer());
      System.out.println("[" + parameter.getParameterIndex() + "]" + parameter.getParameterType().getSimpleName() + "" + parameter.getParameter());
    }
  }

  private static HttpServletRequest mockRequest() {
    MockHttpServletRequest request = new MockHttpServletRequest();
    request.setParameter("name1", "zhangsan");
    request.setParameter("name2", "lisi");
    request.addPart(new MockPart("file", "abc", "hello".getBytes(StandardCharsets.UTF_8)));
    Map<String, String> uriTemplateVariables = new AntPathMatcher()
            .extractUriTemplateVariables("/test/{id}", "/test/123");
    request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVariables);
    request.setContentType("application/json");
    request.setCookies(new Cookie("token", "123456"));
    request.setParameter("name", "张三");
    request.setParameter("age", "18");
    request.setContent("".getBytes());
    return request;
  }

  static class Controller {
    public void test(
            @RequestParam("name1") String name1,
            String name2,
            @RequestParam("age") int age,
            @RequestParam(name = "home", defaultValue = "${JAVA_HOME}") String home1,
            @RequestParam("file") MultipartFile file,
            @PathVariable("id") int id,
            @RequestHeader("Content-Type") String header,
            @CookieValue("token") String token,
            @Value("${JAVA_HOME}") String home2,
            HttpServletRequest request,
            @ModelAttribute User user1,
            User user2,
            @RequestBody User user3
    ) {

    }
  }

  static class User {
    private String name;
    private int age;

    public String getName() {
      return name;
    }

    public void setName(String name) {
      this.name = name;
    }

    public int getAge() {
      return age;
    }

    public void setAge(int age) {
      this.age = age;
    }
  }
}

